package com.hjh.tool.util.sys

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.provider.Settings
import android.telephony.TelephonyManager
import androidx.annotation.RequiresApi
import androidx.annotation.RequiresPermission
import androidx.core.content.ContextCompat
import com.elvishew.xlog.XLog

/**
 * @author： hjh
 * @createDate： 2025/6/9 13:49
 * @description： 系统工具类
 * @note：Android 10+ 需申请权限，且定义系统应用，参考 lib-common 模块下 AndroidManifest.xml
 * @permission:
   <uses-permission
       android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
       tools:ignore="ProtectedPermissions" />
 * @qq： 3472903821
 * @version: 1.0
 */
@Suppress("unused")
@SuppressLint("ObsoleteSdkInt")
object UniqueIdUtil {

    /**
     * 获取复合设备标识（优先IMEI，失败时返回Android ID）
     */
    fun getCompositeDeviceId(context: Context): String {
        return getIMEI(context) ?: getAndroidId(context)
    }

    /**
     * 获取 Android ID（无需特殊权限）
     */
    @SuppressLint("HardwareIds")
    fun getAndroidId(context: Context): String {
        return try {
            Settings.Secure.getString(
                context.contentResolver,
                Settings.Secure.ANDROID_ID
            ).takeIf { !it.isNullOrEmpty() } ?: "unknown_android_id"
        } catch (e: Settings.SettingNotFoundException) {
            "android_id_error"
        }
    }

    /**
     * 获取 IMEI 号
     * 安卓 10+ 需要系统签名及系统权限
     */
    @SuppressLint("HardwareIds", "MissingPermission")
    fun getIMEI(context: Context): String? {
        return try {
            when {
                // Android 10+ 系统应用
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && hasPrivilegedAccess(context) -> {
                    (context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager).imei
                }
                // Android 6.0+ 普通应用
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> {
                    if (hasPrivilegedAccess(context)) {
                        getLegacyDeviceId(context)
                    } else {
                        null
                    }
                }
                // Android 5.1 及以下
                else -> getLegacyDeviceId(context)
            }
        } catch (e: Exception) {
            XLog.e("IMEI获取失败: ${e.message}")
            null
        }
    }

    // Android 5.1 及以下
    @Suppress("DEPRECATION")
    @SuppressLint("ObsoleteSdkInt", "HardwareIds")
    @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE")
    private fun getLegacyDeviceId(context: Context): String? {
        val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        return when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> tm.imei
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> tm.deviceId
            else -> try {
                tm::class.java.getMethod("getDeviceId").invoke(tm) as? String
            } catch (e: Exception) {
                null
            }
        }
    }

    @Suppress("MemberVisibilityCanBePrivate")
    fun hasPrivilegedAccess(context: Context): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            checkPrivilegedPermission(context)
        } else {
            // Android 9及以下版本默认允许访问
            ContextCompat.checkSelfPermission(
                context,
                Manifest.permission.READ_PHONE_STATE
            ) == PackageManager.PERMISSION_GRANTED
        }
    }

    @SuppressLint("PrivateApi")
    @RequiresApi(Build.VERSION_CODES.Q)
    private fun checkPrivilegedPermission(context: Context): Boolean {
        return try {
            val permission = Class.forName("android.Manifest\$permission")
                .getDeclaredField("READ_PRIVILEGED_PHONE_STATE")
                .get(null) as String
            ContextCompat.checkSelfPermission(
                context,
                permission
            ) == PackageManager.PERMISSION_GRANTED
        } catch (e: Exception) {
            false
        }
    }
}